using System;
using System.Collections.Generic;
using System.Linq;

namespace InfiniTec.Collection.Generic
{
    public static class EnumerableExtension
	{
		public static void Foreach<T>(this IEnumerable<T> items, Action<T> action)
		{
			if (items == null) throw new ArgumentNullException("items");
			if (action == null) throw new ArgumentNullException("action");

			foreach (var item in items)
			{
				action(item);
			}
		}

		public static IEnumerable<T> NotNull<T>(this IEnumerable<T> values)
			where T:class 
		{
			return values.Where(item => item != null);
		}

		public static IEnumerable<T> NotNull<T, K>(this IEnumerable<T> values, Func<T, K> selector)
			where K: class
		{
			return values.Where(item => selector(item) != null);
		}

		public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> getChildren)
		{
			if (items == null)
			{
				throw new ArgumentNullException("items");
			}
			if (getChildren == null)
			{
				throw new ArgumentNullException("getChildren");
			}

			foreach (var item in items)
			{
				yield return item;
				var children = getChildren(item);
				foreach (var child in children.Flatten(getChildren))
				{
					yield return child;
				}
			}
		}
	}
}